﻿using System.Collections;
using System.Collections.Generic;
using System.Text.RegularExpressions;

namespace SuperGo.SilverlightLib.Sgf {
    internal class SgfToken {
        public int Index { get; private set; }
        public Regex Regex { get; private set; }
        public string Value { get; private set; }
        public static int MaxIndex { get; private set; }
        public static readonly Dictionary<int, SgfToken> _mapping = new Dictionary<int, SgfToken>();

        public static SgfToken UcLetter = new SgfToken(0, new Regex(@"^[A-Z]"));             // "A".."Z"
        public static SgfToken Digit = new SgfToken(1, new Regex(@"^[0-9]"));                // "0".."9"
        public static SgfToken None = new SgfToken(2, new Regex(@"^"));                      // ""
        public static SgfToken Number = new SgfToken(3, new Regex(@"^[+-]?[0-9]+"));         // [("+"|"-")] Digit { Digit }
        public static SgfToken Real = new SgfToken(4, new Regex(@"^[+-]?[0-9]+\.[0-9]+"));   // Number ["." Digit { Digit }]
        public static SgfToken Double = new SgfToken(5, new Regex(@"^[12]"));                // ("1" | "2")
        public static SgfToken Color = new SgfToken(6, new Regex(@"^[BW]"));                 // ("B" | "W")
        public static SgfToken SimpleText = new SgfToken(7, new Regex(@"^([^:\]\\]|\\.)*")); // { any character (handling see below) }
        public static SgfToken Text = new SgfToken(8, new Regex(@"^([^:\]\\]|\\.)*"));       // { any character (handling see below) }
        public static SgfToken Point = new SgfToken(9, new Regex(@"^[a-zA-Z][a-zA-Z]"));     // game-specific
        public static SgfToken Move = new SgfToken(10, new Regex(@"^[a-zA-Z][a-zA-Z]"));     // game-specific
        public static SgfToken Stone = new SgfToken(11, new Regex(@"^[BW]"));                // game-specific

        private SgfToken(int index, Regex regex) {
            Index = index;
            Regex = regex;
            if (index > MaxIndex) {
                MaxIndex = index;
            }
            if (!_mapping.ContainsKey(index)) {
                _mapping.Add(index, this);
            }
        }

        private SgfToken(int index, Regex regex, string value)
            : this(index, regex) {
            Value = value;
        }

        public static IEnumerable Tokens {
            get { return _mapping.Values; }
        }

        public static SgfToken Get(int index) {
            return _mapping[index];
        }

        public SgfToken CloneWithValue(string value) {
            return new SgfToken(Index, Regex, value);
        }
    }
}
